#ifndef __EVENTFD_HPP__
#define __EVENTFD_HPP__

#include "func.h"
#include <cerrno>
#include <cstdlib>
#include <netinet/in.h>
#include <sys/eventfd.h>
#include <poll.h>

#include <functional>
namespace wd{

class Eventfd{
    using EventCallback = std::function<void()>;
public:
    Eventfd(EventCallback && cb)
    :_eventfd(eventfd_create())
    ,_cb(std::move(cb))
    ,_isStarted(false){

    }

    ~Eventfd(){ close(_eventfd); }

    //子线程的入口函数
    void start(){
        struct pollfd pfd;
        pfd.fd = _eventfd;
        pfd.events = POLLIN;
        
        _isStarted = true;
        while(_isStarted == true){
            int nready = poll(&pfd,1,6000);
            if(nready == -1 && errno ==EINTR){
                continue;
            }else if(nready == -1){
                perror("poll");
                return;
            }else if(nready == 0){
                printf("poll timeout \n");
            }else{
                handleReadEvent();
                if(_cb){
                    _cb();
                }

            }

        }
    }

    void wakeup(){
        uint64_t one = 1;
        int ret = write(_eventfd, &one, sizeof(one));
        if(ret != sizeof(one)){
            perror("write");
        }
    }

    void stop(){
        _isStarted = false;
    }

private:
    int eventfd_create(){
        int ret = eventfd(0,0);
        if(ret < 0){
            perror("eventfd");
            exit(EXIT_FAILURE);
        }
        return ret;
    }
    //将内核的数据清空
    void handleReadEvent(){
        uint64_t howmany = 0;
        int ret = read(_eventfd, &howmany, sizeof(howmany));
        printf("howmany : %ld \n", howmany);
        if(ret != sizeof(howmany)){
            perror("read");
        }
    }
private:
    int _eventfd;
    EventCallback _cb;
    bool _isStarted;
};


}

#endif // __EVENTFD_HPP__

